package com.boot.utils;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {
    final static int CONNECT_TIMEOUT = 5000;
    final static int SOCKET_TIMEOUT = 5000;

    private static final CloseableHttpClient HTTP_CLIENT;
    static {
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(100); // 最大连接数
        cm.setDefaultMaxPerRoute(20); // 每个路由最大连接数
        HTTP_CLIENT = HttpClients.custom()
                .setConnectionManager(cm)
                .build();
    }

    public static String doGet(String url, Map<String, String> paramMap, Map<String, String> headerMap) throws Exception {
        String result = null;
        CloseableHttpResponse response = null;
        //创建httpClient
        try {
            //使用URIBuilder拼接请求
            URIBuilder uriBuilder = new URIBuilder(url);
            if (paramMap != null) {
                for (String key : paramMap.keySet()) {
                    uriBuilder.setParameter(key, paramMap.get(key));
                }
            }
            //生成最终url
            URI uri = uriBuilder.build();
            HttpGet httpGet = new HttpGet(uri);
            //写请求头
            if (headerMap != null) {
                for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                    httpGet.setHeader(entry.getKey(), entry.getValue());
                }
            }
            //发送请求
            response = HTTP_CLIENT.execute(httpGet);
            //如果成功，封装返回体
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public static String doPost(String url, Map<String, String> paramMap, Map<String, String> headerMap) {

        String result = null;
        CloseableHttpResponse response = null;

        //创建httpClient
        try {
            HttpPost httpPost = new HttpPost();
            //创建参数列表
            if (paramMap != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                    paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "UTF-8");
                httpPost.setEntity(entity);
            }
            //写请求头
            if (headerMap != null) {
                for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

           httpPost.setConfig(builderRequestConfig());
            //发送请求
            response = HTTP_CLIENT.execute(httpPost);
            //如果成功，封装返回体
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    private static RequestConfig builderRequestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setConnectionRequestTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT).build();
    }
}
